/*
 * Copyright @ 苏州瑞云信息技术有限公司 All rights reserved.
 */
package work.base.lambda;

import lombok.NoArgsConstructor;
import work.base.lambda.example.Example;

/**
 * @author Sakura Shen
 * 自定义函数式接口
 * Lambda表达式是对实现了函数式接口的对象的一种简写形式 （创建对象) 也就是说
 * Lambda表达式本身就是个对象
 *
 * 把实现代码的部分放在最外层方法的参数中
 *
 * 注意
 *      1 Lambda表达式中不能修改外部变量, 也就是不能修改基本数据类型的值和引用数据类型的引用
 *        不能把引用变量指向其他的实际内存对象 , 但是可以通过引用修改实际对象的内容, 比如 list.add()
 *
 */
@NoArgsConstructor
public class Lambda {

   static final String salutation = "Hello! ";

   // 1 自定义函数式接口
    interface MathOperation {
        int operation(int a, int b);
    }

    // 自定义函数式接口
    interface GreetingService {
        void sayMessage(String message);
    }


    // 2 使用函数式接口作为参数的方法
    // 内部需要调用接口的方法实现代码
    // 相当于起到中间承接的作用
    private int operate(int a, int b, MathOperation mathOperation){
        return mathOperation.operation(a, b);
    }

    public static void main(String args[]){

        Lambda tester = new Lambda();

        // 类型声明
        MathOperation addition = (int a, int b) -> a + b;

        // 匿名类
        // addition相当于定义了一个实现MathOperation接口的匿名类的对象
        MathOperation addition1 = new MathOperation(){
            @Override
            public int operation(int a, int b) {
                return 0;
            }
        };


        // 3 真正实现函数式接口中的方法
        Integer sum = tester.operate(10, 5,
                (a,b) -> {
                    int aaa = 100;
                    return aaa + a + b + 100;
                });
        System.out.println("输出结果为 = " +  sum);


        // 不用类型声明
        MathOperation subtraction = (a, b) -> a - b;
        // 大括号中的返回语句
        MathOperation multiplication = (int a, int b) -> { return a * b; };
        // 没有大括号及返回语句
        MathOperation division = (int a, int b) -> a / b;

        System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
        System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + tester.operate(10, 5, division));

        /**
         * Lambda 允许把函数作为一个方法的参数（函数作为参数传递进方法中）。
         */
        System.out.println("10 + 5 + 100 = " + tester.operate(10, 5, (a,b) -> a+b+100));



        // 创建实现了
        // 不用括号
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);

        // 用括号
        GreetingService greetService2 = (message) ->
                System.out.println(salutation + message);

        greetService1.sayMessage("Runoob");
        greetService2.sayMessage("Google");

    }

}
